package com.seari.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.seari.constant.Const;
import com.seari.entity.ArticleInfo;
import com.seari.entity.PlannedCurrentLimitation;
import com.taobao.api.ApiException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.seari.utils.DateUtil.getNowDateStr;

public class DingUtil {

    private static String corpId = "ding38c46ef492978e7335c2f4657eb6378f";//企业id
    private static String corpSecret = "vwjGdD4rDr-pUE0ej0rzo63ktCC6v2VnFIc3rexpu3-N2C46xXCoTVwje2ZRtiT6";//企业的密钥
    private static String appKey = "dingh7bfh3i33ct8wvvx";//应用唯一标识key
    private static String appSecret = "lqUlWXDF20a-r2JPfqooLizaMgdlKOIXnNNONp2j8S-Ir3M17kiwUEbto4J_HYGy";//应用的密钥

    public static String processCode = "PROC-C3148628-C9BD-4259-9205-3D2596495735";//流程模板唯一标识(审批)
    public static String corpAccessToken = "a15a8c77612837f7884a7a352b0b1617";//调用企业接口凭证(以corpId+corpSecret生成)
    public static String appAccessToken = "9bf4fba672e039ffb85556bdea266211";//调用企业接口凭证(以appKey+appSecret生成)有效时间：7200秒


    private static String dateTime = "2020-04-23T14:52:40";//token缓存时间
    private static String accessToken = "";
    private static long expiresIn = 0L;

    /**
     * 提供accessToken
     * @return
     */
    public static String getAccessToken() {
        LocalDateTime nowTime = LocalDateTime.now();
        LocalDateTime oldTime = LocalDateTime.parse(dateTime);

        Duration duration = Duration.between(oldTime, nowTime);
        if (duration.toMillis() >= expiresIn || StringUtil.isEmpty(accessToken))//单位/毫秒 根据钉钉返回token的过期时间 转换为毫秒并对比
        {
            postDingAccessToken("app");
            dateTime = nowTime.toString();
            return accessToken;
        }
        return accessToken;
    }

    public static void main(String[] args) {
        System.out.println("DingUtil="+DingUtil.getAccessToken());
    }

    /**
     * 获取钉钉Access_token
     * tokenType:corp=以corpId+corpSecret生成;app=以appKey+appSecret生成
     * 获取调用企业接口凭证。参数传入corpid、corpsecret 或 appkey、appsecret，不需全部填写。
     * @return
     */
    public static String postDingAccessToken(String tokenType) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
            OapiGettokenRequest req = new OapiGettokenRequest();
            if (StringUtil.isNotEmpty(tokenType) && tokenType.equals("corp")) {
                req.setCorpid(corpId);
                req.setCorpsecret(corpSecret);
            } else if (StringUtil.isNotEmpty(tokenType) && tokenType.equals("app")) {
                req.setAppkey(appKey);
                req.setAppsecret(appSecret);
            }
            req.setHttpMethod("GET");
            OapiGettokenResponse rsp = client.execute(req);
            if (StringUtil.isNotEmpty(rsp.getBody())) {
                JSONObject jsonObject = JSONObject.parseObject(rsp.getBody());
                if (jsonObject.getInteger("errcode") == 0 && "ok".equals(jsonObject.getString("errmsg"))) {
                    accessToken = jsonObject.getString("access_token");
                    expiresIn = jsonObject.getLong("expires_in") * 1000;//获取返回的过期时间并转为毫秒
                }

            }
            return rsp.getBody();
        } catch (ApiException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取用户创建的填表
     * bizType:填表类型。0表示通用智能填表，1表示教育版填表
     * userId:填表模板创建人userid
     * offset:分页起始，从0开始。当返回结果中has_more为false时，表示没有下一页了。否则取返回结果中next_cursor的值作为下一次请求的offset
     * size:分页大小，最大200
     * @return
     */
    public static String getFormList(String accessToken, Long bizType, String userId, Long offset, Long size) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/collection/form/list");
        OapiCollectionFormListRequest req = new OapiCollectionFormListRequest();
        req.setBizType(bizType);
        req.setCreator(userId);
        req.setOffset(offset);
        req.setSize(size);
        req.setHttpMethod("POST");
        OapiCollectionFormListResponse rsp = client.execute(req, accessToken);
        return rsp.getBody();
    }

    /**
     * 获取填表实例数据
     * formCode:填表code
     * actionDate:时间，必须是YYYY-MM-DD的格式
     * offset:分页起始，从0开始。当返回结果中has_more为false时，表示没有下一页了。否则取返回结果中next_cursor的值作为下一次请求的offset
     * size:分页大小，最大100
     * @return
     */
    public static String getInstanceList(String accessToken, String formCode, String actionDate, Long offset, Long size) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/collection/instance/list");
        OapiCollectionInstanceListRequest req = new OapiCollectionInstanceListRequest();
        req.setFormCode(formCode);
        req.setActionDate(actionDate);
        req.setOffset(offset);
        req.setSize(size);
        OapiCollectionInstanceListResponse rsp = client.execute(req, accessToken);
        return rsp.getBody();
    }

    /**
     * 分页获取审批实例id列表
     *
     * @return
     */
    public static String getApprovalList(String accessToken, Long startTime, Long endTime, Long size, Long cursor, String useridList) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/listids");
            OapiProcessinstanceListidsRequest req = new OapiProcessinstanceListidsRequest();
            req.setProcessCode(DingUtil.processCode);
            req.setStartTime(startTime);//long类型
            if (endTime != null)
                req.setEndTime(endTime);//long类型
            if (size != null)
                req.setSize(size);//一页显示条数
            if (cursor != null)
                req.setCursor(cursor);//页码
            if (useridList != null)
                req.setUseridList(useridList);//发起人用户id列表
            OapiProcessinstanceListidsResponse rsp = client.execute(req, accessToken);
            return rsp.getBody();
        } catch (ApiException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取单个审批实例详情
     *
     * @return
     */
    public static String getSingleInstanceDetails(String processInstanceId, String accessToken) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/get");
            OapiProcessinstanceGetRequest req = new OapiProcessinstanceGetRequest();
            req.setProcessInstanceId(processInstanceId);
            OapiProcessinstanceGetResponse rsp = client.execute(req, accessToken);
            return rsp.getBody();
        } catch (ApiException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 将拿到的填表实例格式转换
     * @return
     */
    public static List<ArticleInfo> formatConversion(String param, Integer articleType) {
        if (StringUtil.isNotEmpty(param)) {
            JSONObject jsonObject = JSONObject.parseObject(param);
            if (!jsonObject.isEmpty() && jsonObject.getInteger("errcode") == 0) {
                List<ArticleInfo> resList = new ArrayList<>();
                JSONObject jsonObj = jsonObject.getJSONObject("result");
                JSONArray jsonArray = jsonObj.getJSONArray("list");
                if (jsonArray != null) {
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsoni = jsonArray.getJSONObject(i);
                        ArticleInfo articleInfo = new ArticleInfo();
                        articleInfo.setId(StringUtil.getId());
                        articleInfo.setArticleType(articleType);
                        articleInfo.setCreateTime(jsoni.getString("create_time"));
                        articleInfo.setSubUserName(jsoni.getString("submitter_user_name"));
                        JSONArray jsonArr = jsoni.getJSONArray("forms");
                        for (int j = 0; j < jsonArr.size(); j++) {
                            JSONObject jsonj = jsonArr.getJSONObject(j);
                            if (Const.ARTICLE_DATE_KEY.containsKey(jsonj.getString("key"))) {
                                articleInfo.setArticleDate(getNowDateStr());
                            }
                            if (Const.ARTICLE_CONTENT_KEY.containsKey(jsonj.getString("key"))) {

                                articleInfo.setArticleContent(jsonj.getString("value"));
                                if(jsonj.getString("value")==null){
                                    articleInfo.setArticleContent("暂无数据");
                                }

                            }
                        }
                        resList.add(articleInfo);
                    }
                }
                return resList;
            }

        }
        return null;
    }

    /**
     * 将拿到的审批ID列表转换未List
     * @return
     */
    public static List<Map<String, String>> getFormatConversionApp(String accessToken, Long startTime, Long endTime, Long size, Long cursor, String useridList) {
        List<Map<String, String>> resList = new ArrayList<>();
        String res = getApprovalList(accessToken, startTime, endTime, size, cursor, useridList);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if (jsonObject.getInteger("errcode") == 0) {
            JSONObject resultJson = jsonObject.getJSONObject("result");
            JSONArray listArr = resultJson.getJSONArray("list");
            if (listArr != null) {
                for (int i = 0; i < listArr.size(); i++) {
                    Map<String, String> map = new HashMap<>();
                    map.put("processCode", listArr.getString(i));
                    resList.add(map);
                }
            }
            if (resultJson.containsKey("next_cursor")) {
                getFormatConversionApp(accessToken, startTime, endTime, size, resultJson.getLong("next_cursor"), useridList);
            }
        }
        return resList;
    }

    /**
     * 将拿到的审批实例转换为List
     * @param param
     * @return
     */
    public static List<PlannedCurrentLimitation> formatConversionPcl(String param) throws ParseException {
        if (StringUtil.isNotEmpty(param)) {
            JSONObject jsonObject = JSONObject.parseObject(param);
            if (!jsonObject.isEmpty() && jsonObject.getInteger("errcode") == 0) {
                List<PlannedCurrentLimitation> pclList = new ArrayList<>();
                JSONObject processInstance = jsonObject.getJSONObject("process_instance");
                //判断审批状态
                if ("agree".equalsIgnoreCase(processInstance.getString("result")) && "COMPLETED".equalsIgnoreCase(processInstance.getString("status"))) {
                    String createTime = processInstance.getString("create_time");
                    JSONArray formComponentValues = processInstance.getJSONArray("form_component_values");
                    if (formComponentValues != null) {
                        for (int i = 0; i < formComponentValues.size(); i++) {
                            JSONObject jsonObjA = formComponentValues.getJSONObject(i);
                            JSONArray valueArr = JSONArray.parseArray(jsonObjA.getString("value"));
                            for (int j = 0; j < valueArr.size(); j++) {
                                JSONObject jsonObjB = valueArr.getJSONObject(j);
                                JSONArray rowValueArr = jsonObjB.getJSONArray("rowValue");
                                PlannedCurrentLimitation pcl = new PlannedCurrentLimitation();
                                pcl.setId(StringUtil.getId());
                                pcl.setCreateTime(createTime);
                                for (int k = 0; k < rowValueArr.size(); k++) {
                                    JSONObject jsonObjC = rowValueArr.getJSONObject(k);
                                    pcl = forValue(pcl, jsonObjC);
                                }
                                pclList.add(pcl);
                            }
                        }
                    }
                }
                return pclList;
            }
        }
        return null;
    }

    /**
     * 遍历返回的json中的限流字段得到起始和结束时间值
     * @param pcl
     * @param json
     * @return
     */
    public static PlannedCurrentLimitation forValue(PlannedCurrentLimitation pcl, JSONObject json) {
        if ("TextField-K2AD4O5B".equals(json.getString("key"))) {
            pcl.setStationName(json.getString("value"));
        } else if ("DDDateRangeField-K9NY9RA1".equals(json.getString("key"))) {
            JSONArray planArr = json.getJSONArray("value");
            pcl.setPlanCurrentLimitingStartTime(planArr.getString(0));
            pcl.setPlanCurrentLimitingEndTime(planArr.getString(1));
        } else if ("DDDateRangeField-K9NY9RA2".equals(json.getString("key"))) {
            JSONArray actuArr = json.getJSONArray("value");
            pcl.setActualCurrentLimitingStartTime(actuArr.getString(0));
            pcl.setActualCurrentLimitingEndTime(actuArr.getString(1));
        } else if ("TextareaField-K9HU27BS".equals(json.getString("key"))) {
            pcl.setRemark(json.getString("value"));
        }
        return pcl;
    }

}
